import router from "./router";
import { ElMessage } from "element-plus";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { getToken } from "@/utils/auth.ts";
import { isHttp } from "@/utils/validate.ts";
import { isRelogin } from "@/utils/request.ts";
import useUserStore from "@/store/modules/user";
import useSettingsStore from "@/store/modules/settings";
import usePermissionStore from "@/store/modules/permission";
import type { RouteLocationNormalized, NavigationGuardNext, RouteRecordRaw } from "vue-router";

NProgress.configure({ showSpinner: false });

const whiteList: string[] = ["/login", "/auth-redirect", "/bind", "/register"];

router.beforeEach(
  async (
    to: RouteLocationNormalized,
    from: RouteLocationNormalized,
    next: NavigationGuardNext
  ) => {
    NProgress.start();
    if (getToken()) {
      if (to.meta?.title) {
        useSettingsStore().setTitle(to.meta.title as string);
      }
      if (to.path === "/login") {
        next({ path: "/" });
        NProgress.done();
      } else {
        const userStore = useUserStore();
        if (userStore.roles.length === 0) {
          isRelogin.show = true;
          try {
            await userStore.getInfo();
            isRelogin.show = false;

            const accessRoutes: RouteRecordRaw[] =
              await usePermissionStore().generateRoutes([]);

            accessRoutes.forEach((route: RouteRecordRaw) => {
              if (route.path && !isHttp(route.path)) {
                router.addRoute(route);
              }
            });

            next({ ...to, replace: true });
          } catch (err: any) {
            await userStore.logOut();
            ElMessage.error(err);
            next({ path: "/" });
          }
        } else {
          next();
        }
      }
    } else {
      // 没有 token
      if (whiteList.includes(to.path)) {
        next();
      } else {
        next(`/login?redirect=${to.fullPath}`);
        NProgress.done();
      }
    }
  }
);

router.afterEach(() => {
  NProgress.done();
});
